package com.axonactive.yolo.util;

import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;

import org.apache.commons.codec.binary.Base64;
import org.apache.log4j.Logger;

import com.axonactive.yolo.controller.FlightController;

public class EncryptDecrypt {
	private static final String UNICODE_FORMAT = "UTF8";
	public static final String DESEDE_ENCRYPTION_SCHEME = "DESede";
	// DONT CHANGE THIS KEY
	public static final String FINAL_KEY = "ThisIsSpartaThisIsSparta";
	private static final Logger LOGGER = Logger.getLogger(EncryptDecrypt.class);

	public static String encryptDES(String unencryptedString){
		String encryptedString = null;

		try {
			byte[] arrayBytes = FINAL_KEY.getBytes(UNICODE_FORMAT);
			KeySpec ks = new DESedeKeySpec(arrayBytes);
			SecretKeyFactory skf = SecretKeyFactory
					.getInstance(DESEDE_ENCRYPTION_SCHEME);
			Cipher cipher = Cipher.getInstance(DESEDE_ENCRYPTION_SCHEME);
			SecretKey key = skf.generateSecret(ks);

			cipher.init(Cipher.ENCRYPT_MODE, key);
			byte[] plainText = unencryptedString.getBytes(UNICODE_FORMAT);
			byte[] encryptedText = cipher.doFinal(plainText);
			encryptedString = new String(Base64.encodeBase64(encryptedText));

		} catch (UnsupportedEncodingException e) {
			LOGGER.error("encryption init error", e);
		} catch (InvalidKeyException e) {
			LOGGER.error("encryption init error", e);
		} catch (NoSuchAlgorithmException e) {
			LOGGER.error("encryption init error", e);
		} catch (NoSuchPaddingException e) {
			LOGGER.error("encryption init error", e);
		} catch (IllegalBlockSizeException e) {
			LOGGER.error("encryption init error", e);
		} catch (BadPaddingException e) {
			LOGGER.error("encryption init error", e);
		} catch (InvalidKeySpecException e) {
			LOGGER.error("encryption init error", e);
		}

		return encryptedString;
	}

	public static String decryptDES(String encryptedString){
		String decryptedText = null;

		try {
			byte[] arrayBytes = FINAL_KEY.getBytes(UNICODE_FORMAT);
			KeySpec ks = new DESedeKeySpec(arrayBytes);
			SecretKeyFactory skf = SecretKeyFactory
					.getInstance(DESEDE_ENCRYPTION_SCHEME);
			Cipher cipher = Cipher.getInstance(DESEDE_ENCRYPTION_SCHEME);
			SecretKey key = skf.generateSecret(ks);

			cipher.init(Cipher.DECRYPT_MODE, key);
			byte[] encryptedText = Base64.decodeBase64(encryptedString
					.getBytes());
			byte[] plainText = cipher.doFinal(encryptedText);
			decryptedText = new String(plainText);
		} catch (UnsupportedEncodingException e) {
			LOGGER.error("decryption init error", e);
		} catch (InvalidKeyException e) {
			LOGGER.error("decryption init error", e);
		} catch (NoSuchAlgorithmException e) {
			LOGGER.error("decryption init error", e);
		} catch (NoSuchPaddingException e) {
			LOGGER.error("decryption init error", e);
		} catch (InvalidKeySpecException e) {
			LOGGER.error("decryption init error", e);
		} catch (IllegalBlockSizeException e) {
			LOGGER.error("decryption init error", e);
		} catch (BadPaddingException e) {
			LOGGER.error("decryption init error", e);
		}

		return decryptedText;
	}

	public static String encryptMD5(String str) {
		MessageDigest md;
		try {
			md = MessageDigest.getInstance("MD5");
			md.update(str.getBytes());

			byte[] byteData = md.digest();
			StringBuilder sb = new StringBuilder();
			for (int i = 0; i < byteData.length; i++) {
				sb.append(Integer.toString((byteData[i] & 0xff) + 0x100, 16)
						.substring(1));
			}

			// convert the byte to hex format method 2
			StringBuilder hexString = new StringBuilder();
			for (int i = 0; i < byteData.length; i++) {
				String hex = Integer.toHexString(0xff & byteData[i]);
				if (hex.length() == 1) {
					hexString.append('0');
				}
				hexString.append(hex);
			}
			LOGGER.info("Digest(in hex format): " + hexString.toString());
			return hexString.toString();

		} catch (NoSuchAlgorithmException e) {
			LOGGER.error("error", e);
		}
		return str;
	}
}